// Copyright (c) 2022.
// Written by Li Yanxiao. All rights reserved

#ifndef SIGNED_DISTANCE_FIELD_BROKEN_LINE_H
#define SIGNED_DISTANCE_FIELD_BROKEN_LINE_H

#include <random>
#include <Eigen/Dense>
#include <ostream>
#include "Line.h"
/*
 * 由于这里包含了Eigen/Dense库
 * 引入broken_line.h后就不用再包含一遍了
 */

/*
 * 生成一个随机点，位置介于 minVal(x1,y1), maxVal(x2,y2)之间，生成的点保存在dst中
*/
unsigned int* RandomDot(unsigned int dst[], unsigned int minVal[], unsigned int maxVal[]);

/*
 * 生成一个随机点，位置介于 minVal(x1,y1), maxVal(x2,y2)之间，生成的点保存在dst中
 * 只是把数据类型从unsigned [2]改成了Eigen::Vector2d
 */
Eigen::Vector2i * RandomDot(Eigen::Vector2i dst[], const Eigen::Vector2i& minVal, const Eigen::Vector2i& maxVal);

/*
 * 生成一条随机的初始线段，这条线段会在width, height的长度之内，并且离其两端至少distance远
 * @returns: 返回这条线段的初始点与终止点。它们都是Eigen::Vector2d
 * @params dst: 将把该列表填入两个点
 * @params width: 该线段x值的最大值（最小值为0）
 * @params height: 该线段y值的最大值（最小值为0）
 * @params distance: 线段x,y值离(0/width)(0/height)的范围
 *
 * 注意：默认的生成范围在（0，0），（300，200）之内，是为了防止生成第二条线的时候可用空间过少，random调用次数
 * 过多导致的程序减速
 * 如果我想到了个更好的生成第二条线的方法，会把这个限制去掉的
 */
Line GenerateFirstLine(unsigned int width=600, unsigned int height=400, unsigned int distance=5);

/*
 * 生成第二条线段，与first_line之间间隔一个钝角
 * @returns:返回表示这条线段的line对象
 * @params *first_line：指向第一条线两个端点构成的数组的指针
 * @params width: 线段x值的最大值（最小为0）
 * @params height: 该线段y值的最大值（最小值为0）
 * @params distance: 线段x,y值离(0/width)(0/height)的范围
 */
Line GenerateSecondLine(const Line &first_line, unsigned width= 600, unsigned height= 400, unsigned distance= 5);

/*
 * 生成第三条线段，与第二条之间间隔一个锐角，并且其延长线与第一条线段的反向延长线不相交。
 * @returns:返回这条线段的line对象
 * @params *first_line：指向第一条线两个端点构成的数组的指针
 * @params *second_line: 指向第二条线两个端点构成的数组的指针
 * @params width: 线段x值的最大值（最小为0）
 * @params height: 该线段y值的最大值（最小值为0）
 * @params distance: 线段x,y值离(0/width)(0/height)的范围
 */
Line GenerateThirdLine(const Line& first_line, const Line& second_line, unsigned width=600, unsigned height=400,
                                    unsigned distance=5);

/*
 * 检查first_line与second_line是否在它们的延伸方向上有交点，交点范围是否在(0,width),(0,height)的范围内
 */
bool collide(const Line& first_line, const Line& second_line, int width=600, int height=400);

/*
 * 生成一整条折线，返回一个指向折线数组的指针
 * @params dst:一个指向Line对象数组的指针，必须是3格大
 * @params width:生成的线段x值最大限制（最小为0）
 * @params height:生成的线段y值最大限制（最小为0）
 * @params distance:生成的线段距离(0,width)/(0,height)的最小值(防止线段生成到边界上了)
 */
Line* GenerateBrokenLine(Line* dst, unsigned width=600, unsigned height=400, unsigned distance=20);

#endif //SIGNED_DISTANCE_FIELD_BROKEN_LINE_H
